home *** CD-ROM | disk | FTP | other *** search
- #pragma inline
- #include <stdio.h>
- #include <alloc.h>
- #include <dos.h>
- #include <process.h>
-
- #include "y_off.h"
-
- //*************************RUTINAS NUEVAS******************************
- //************REQUIEREN OPTIMZACIαN A NIVEL DE ENSAMBLADOR*************
- //MACROS ΘTILES
- #define ABS(a) ((a < 0) ? -a : a)
- #define SGN(a) ((a < 0) ? -1 : 1)
- #define XCHG(a,b,c) ((c=a),(a=b),(b=c))
- #define OFFS(x,y) (y_off[y]+x)
-
-
- typedef struct
- {
- int x,y,z;
- } VERTEX_3D;
-
- int getoff(void);
- int valloc( unsigned long asize );
- void vfree( int segm );
-
- int array_flag=0, dbg_cnt;
- int SCRN=0xA000;
- int far *x_array, far *closed_ptr;
- unsigned int w_array, closed;
- extern int old_mode;
-
- // Función: _putpixel
- // Pone el pixel de la pantalla del color especificado
- void putpixel( int x, int y, int color)
- { unsigned int off;
- asm{
- mov ax,x
- mov bx,y
- };
- getoff();
- asm{
- mov di,ax
- mov ax,0A000h
- mov es,ax
- mov ax,color
- stosb
- };
- }
-
- //linea entre (x1,y1) y (x2,y2), del color especificado.
- void linea( int x1, int y1, int x2, int y2, int color )
- { unsigned int frac, xac, pre_xac, absdx, absdy;
- int intg, x, y, dy, dx;
- unsigned long acum, delta;
-
- dx=1;
- dy=1;
-
- if(x1>x2)
- dx=-1;
-
- if(y1>y2)
- dy=-1;
-
- acum= (long) (ABS((x2-x1)));
- acum<<=16;
- delta=(long) (ABS((y2-y1)));
- if(delta==0L)
- dy=0;
- else
- delta=acum/delta;
- frac=(int) (delta&0xFFFFL);
- intg=(int) (delta>>16);
- if(dx<1)
- intg=-intg;
- x=x1;
- y=y1;
- xac=frac;
- do{
- putpixel( x, y, color);
- y+=dy;
- pre_xac=xac;
- xac+=frac;
- if(xac<pre_xac)
- x+=dx;
- x+=intg;
- }while(y!=y2);
- putpixel( x2, y2, color );
- }
-
- /*
- Para que la función de sombreado interpolativo funcione, es necesario
- que haya un apartado en la paleta de 16 colores (en esta primera fase)
- que contenga una gama de colores (desde intensidad 0, hasta casi blanco
- del mismo color). comenzarán en el color designado por el parámetro
- así llamado, en cuyo lugar se encontrará el mas obscuro de ellos, a
- continuación se irá incrementando la intensidad del color hasta el
- máximo (luminosidad del 80% ). a futuro es posible efectuar el sombreado
- de forma que la paleta corresponda con la intensidad relativa del color
- para un sombreado entero, ajustando la paleta cada vez que sea necesario.
- igualmente, ajustando el gradiente de intensidad. Incluso tal vez sea
- posible que los colores utilizados no tengan un número fijo, sino que
- sean variables de acuerdo a lo necesario.
- */
-
- int colr[2048];
- int MAX_COL=84;
- int MIN_COL=20;
- int MAX_DIST=50;
-
- void drawpol1( VERTEX_3D *pol, int lados )
- { int mxcnt, mxc, mny, mxy, cuenta, sgn, ptr, offs;
- int x1,y1,z1,x2,y2,z2, NUM_COL;
- long d_col, r_col;
- char far *SCR;
-
- NUM_COL=MAX_COL-MIN_COL;
-
- d_col=(long)NUM_COL;
- d_col<<=16;
- d_col/=(long)MAX_DIST;
-
- //Cerrar el polígono
- asm{
- cld
- les di,pol
- mov bx,lados
- mov ax,bx
- shl bx,2
- shl ax,1
- add bx,ax
- mov eax,es:di
- mov es:[di+bx],eax
- mov ax,es:[di+4]
- add bx,4
- mov es:[di+bx],ax
- };
-
- //Obtener y máxima y mínima
- for( cuenta=1, mny=mxy=0; cuenta<4; cuenta++)
- {
- if(pol[mny].y>pol[cuenta].y)
- mny=cuenta;
-
- if(pol[mxy].y<pol[cuenta].y)
- mxy=cuenta;
- };
-
- if( mny==mxy ) //si la altura del polígono es cero, salir
- return;
-
- mxcnt=pol[mxy].y-pol[mny].y;
-
- BACKWD:
- ptr=mny;
- cuenta=0;
- do{
- if(ptr<=0)
- ptr=lados;
-
- int y1=pol[ptr].y;
- int y2=pol[ptr-1].y;
-
- int x1=pol[ptr].x;
- int x2=pol[ptr-1].x;
-
- sgn=1;
- long delta=(long)x2;
- delta-=(long)x1;
- if(delta<0L)
- {
- delta=-delta;
- sgn=-1;
- };
-
- long delta1=(long)y2;
- delta1-=(long)y1;
- if(delta1==0)
- {
- ptr--;
- continue;
- };
- delta<<=16;
- delta/=delta1;
- delta1=(long)x1;
- delta1<<=16;
-
- while(y1<y2)
- {
- x1=(int)(delta1>>16);
-
- x_array[cuenta]=x1;
- if(sgn<0)
- delta1-=delta;
- else
- delta1+=delta;
- y1++;
- cuenta+=2;
- };
- ptr--;
- }while(ptr!=mxy);
-
- FORWD:
- ptr=mny;
- cuenta=1;
- if(ptr>=lados)
- ptr=0;
-
- do{
-
- int y1=pol[ptr].y;
- int y2=pol[ptr+1].y;
-
- int x1=pol[ptr].x;
- int x2=pol[ptr+1].x;
-
- sgn=1;
- long delta=(long)x2;
- delta-=(long)x1;
- if(delta<0L)
- {
- delta=-delta;
- sgn=-1;
- };
-
- long delta1=(long)y2;
- delta1-=(long)y1;
-
- if(delta1==0)
- {
- ptr++;
- continue;
- };
- delta<<=16;
- delta/=delta1;
- delta1=(long)x1;
- delta1<<=16;
-
- while(y1<y2)
- {
- x1=(int)(delta1>>16);
-
- x_array[cuenta]=x1;
- if(sgn<0)
- delta1-=delta;
- else
- delta1+=delta;
- y1++;
- cuenta+=2;
- };
- ptr++;
- if(ptr>=lados)
- ptr=0;
-
- }while(ptr!=mxy);
-
- SHADE_1:
-
- ptr=mny;
- cuenta=0;
- do{
- if(ptr<=0)
- ptr=4;
-
- int y1=pol[ptr].y;
- int y2=pol[ptr-1].y;
-
- int z1=pol[ptr].z;
- int z2=pol[ptr-1].z;
-
- sgn=1;
- long delta=(long)z2;
- delta-=(long)z1;
- if(delta<0L)
- {
- delta=-delta;
- sgn=-1;
- };
-
- long delta1=(long)y2;
- delta1-=(long)y1;
- if(delta1==0)
- {
- ptr--;
- continue;
- };
- delta<<=16;
- delta/=delta1;
- delta1=(long)z1;
- delta1<<=16;
-
- while(y1<y2)
- {
- z1=(int)(delta1>>16);
- r_col=(long)z1 * d_col;
-
- if( r_col>((long)MAX_COL<<16))
- r_col=(long)(MAX_COL<<16);
- if( r_col<0 )
- r_col=0;
-
- colr[cuenta]=(int)(r_col>>16);
-
- if(sgn<0)
- delta1-=delta;
- else
- delta1+=delta;
- y1++;
- cuenta+=2;
- };
- ptr--;
- }while(ptr!=mxy);
-
- SHADE_2:
- ptr=mny;
- cuenta=1;
- do{
- if(ptr>=(4))
- ptr=0;
-
- int y1=pol[ptr].y;
- int y2=pol[ptr+1].y;
-
- int z1=pol[ptr].z;
- int z2=pol[ptr+1].z;
-
- sgn=1;
- long delta=(long)z2;
- delta-=(long)z1;
- if(delta<0L)
- {
- delta=-delta;
- sgn=-1;
- };
-
- long delta1=(long)y2;
- delta1-=(long)y1;
- if(delta1==0)
- {
- ptr++;
- continue;
- };
- delta<<=16;
- delta/=delta1;
- delta1=(long)z1;
- delta1<<=16;
-
- while(y1<y2)
- {
- z1=(int)(delta1>>16);
- r_col=(long)z1 * d_col;
-
- if( r_col>((long)MAX_COL<<16))
- r_col=(long)(MAX_COL<<16);
- if( r_col<0 )
- r_col=0;
-
- colr[cuenta]=(int)(r_col>>16);
-
- if(sgn<0)
- delta1-=delta;
- else
- delta1+=delta;
- y1++;
- cuenta+=2;
- };
- ptr++;
- }while(ptr!=mxy);
-
- RENDER:
-
- SCR=(char far *)MK_FP( SCRN, 0 );
- y2=pol[mny].y;
-
- for( y1=0; y1<mxcnt; y1++ )
- {
- x1=x_array[y1*2];
- x2=x_array[y1*2+1];
- r_col=(long)(colr[y1*2]);
- d_col=(long)(colr[y1*2+1]);
- d_col-=r_col;
- if(d_col<0L)
- {
- d_col=-d_col;
- sgn=1;
- }
- else
- sgn=-1;
-
- d_col<<=16;
- long delta=(x2-x1);
- if(delta!=0)
- d_col/=delta;
- else
- d_col=0;
- offs=y_off[y2];
- while(x1!=x2)
- {
- SCR[offs+x1]=(int)(r_col>>16);
- r_col+=d_col;
- x1++;
- };
- };
- }
-
- /* FUNCIαN: _drawpoly
- Dibuja polígonos llenos, sólo polígonos convexos.
- parámetros:
- pol: arreglo secuencial x, y, x, y, de enteros
- lados: Numero de lados del polígono
- color: Color del polígono
- */
- void drawpoly( int far *pol, int lados, int color)
- { int mxc, mny, mxy, index, cuenta, mxcnt, scrn, DC, min,
- min2, max;
- long color1;
-
- //Proteger el puntero de pantalla
- scrn=SCRN;
- DC=0;
- //Cerrar el polígono
- asm{
- cld
- mov es,closed
- mov cx,lados
- push ds
- lds si,pol
- xor di,di
- rep movsd
- lds si,pol
- movsd
- };
-
- //Obtener y máxima y mínima
- for( cuenta=3, mny=mxy=1; cuenta<=(lados*2); cuenta+=2)
- {
- if(closed_ptr[mny]>closed_ptr[cuenta])
- mny=cuenta;
-
- if(closed_ptr[mxy]<closed_ptr[cuenta])
- mxy=cuenta;
- };
-
- if( mny==mxy )
- return;
-
- min=closed_ptr[mny];
- if(min<0)
- min=-min;
- else
- min=0;
- min2=min;
- max=closed_ptr[mxy];
- if(max>319)
- max=319;
- if(max<0)
- return;
-
- mxcnt=closed_ptr[mxy]-closed_ptr[mny];
-
- asm{
- mov ax,mny //mny para que apunte a la x en bytes
- add ax,ax
- sub ax,2
- mov mny,ax
- mov ax,mxy //mxy para que apunte a la x en bytes
- add ax,ax
- sub ax,2
- mov mxy,ax
- mov ax,lados //mxc a un valor en bytes, para comparación.
- add ax,ax
- add ax,ax
- mov mxc,ax
- };
-
- BACKWD:
- asm{
- push ds //proteger el segmento
- les di,x_array
- lds si,closed_ptr//cargar los punteros: (origen=pol; destino=x_array)
- mov si,mny
- };
- label0:
- asm{
- cmp si,4 //si SI está en el límite inferior, continuar arriba
- jge index1
- mov si,mxc
- cmp si,mxy
- jne index1
- jmp salida1
- };
- index1:
- asm{
- mov ax,[si] //cargar X y Y para obtener offset, proteger a la
- mov bx,[si+2]//vez sus valores para uso posterior
- mov dx,ax
- mov cx,bx
- push ds ax
- mov ax,seg y_off
- mov ds,ax
- add bx,bx
- pop ax
- add ax,[offset y_off + bx ]
- xor bx,bx // para uso posterior de bx como indicador de signo
- pop ds
- push ax //proteger el valor del offset
- sub dx,[si-4]//obtener el valor delta
- jns pos_1a
- xor bx,1
- neg dx
- };
- pos_1a:
- asm{
- sub cx,[si-2]
- neg cx //corregir la resta negativa
- add word ptr DC,cx
- cmp word ptr DC,320
- jbe no_jmp1
- jmp salida_p
- };
- no_jmp1:
- asm{
- mov ax,dx
- shl eax,16
- movsx ecx,cx
- xor edx,edx
- jcxz y_es_cero1 //Evitar división por cero
- idiv ecx
- jmp y_no_es_cero1
- };
- y_es_cero1:
- asm{
- pop ax
- sub si,4
- cmp si,mxy
- jne label0
- jmp salida1
- };
- y_no_es_cero1:
- asm{
- rol eax,16 //convertirlo en una variable flotante para su uso
- mov edx,eax
- xor eax,eax
- pop ax //recuperar el offset
- cmp word ptr min,0
- jnz dummy1
- or bx,bx
- jz label1a
- };
- label1:
- asm{
- mov es:di,ax//poner el offset en la variable
- add di,4
- add eax,edx
- adc ax,320 //calcular el nuevo offset
- loop label1 //hasta terminar con el valor y2-y
- sub si,4
- cmp si,mxy
- je no_jmp1b
- jmp label0
- };
- no_jmp1b:
- asm{
- jmp salida1
- };
- label1a:
- asm neg dx
- label1b:
- asm{
- mov es:di,ax//poner el offset en la variable
- add di,4
- add eax,edx
- sbb ax,-320 //calcular el nuevo offset
- loop label1b//hasta terminar con el valor y2-y
- sub si,4
- cmp si,mxy
- je salida1
- jmp label0
- };
- dummy1:
-
-
- salida1:
- FORWD:
- asm{
- mov word ptr DC,0
- mov di,2
- mov si,mny
- };
- label02:
- asm{
- cmp si,mxc //si SI está en el límite inferior, continuar arriba
- jl index12
- mov si,0
- cmp si,mxy
- jne index12
- jmp salida12
- };
- index12:
- asm{
- mov ax,[si] //cargar X y Y para obtener offset, proteger a la
- mov bx,[si+2]//vez sus valores para uso posterior
- mov dx,ax
- mov cx,bx
- push ds ax
- mov ax,seg y_off
- mov ds,ax
- add bx,bx
- pop ax
- add ax,[offset y_off + bx ]
- xor bx,bx // para uso posterior de bx como indicador de signo
- pop ds
- push ax //proteger el valor del offset
- sub dx,[si+4]//obtener el valor delta
- jns pos_1a2
- xor bx,1
- neg dx
- };
- pos_1a2:
- asm{
- sub cx,[si+6]
- jns pos2
- neg cx
- };
- pos2:
- asm{
- add word ptr DC,cx
- cmp word ptr DC,320
- jne no_jmp2
- jmp salida_p
- };
- no_jmp2:
- asm{
- mov ax,dx
- shl eax,16
- movsx ecx,cx
- xor edx,edx
- jcxz y_es_cero12//Evitar división por cero
- idiv ecx
- jmp y_no_es_cero12
- };
- y_es_cero12:
- asm{
- pop ax
- add si,4
- cmp si,mxy
- jne label02
- jmp salida12
- };
- y_no_es_cero12:
- asm{
- rol eax,16 //convertirlo en una variable flotante para su uso
- mov edx,eax
- pop ax //recuperar el offset
- or bx,bx
- jz label1a2
- };
- label12:
- asm{
- mov es:di,ax //guardar el offset primero
- add di,4 //calcular el siguiente
- add eax,edx
- adc ax,320
- sub cx,1 //hasta terminar con el valor y2-y
- jz term2a
- mov es:di,ax
- add di,4
- add eax,edx
- adc ax,320 //calcular el nuevo offset
- loop label12 //hasta terminar con el valor y2-y
- };
- term2a:
- asm{
- add si,4
- cmp si,mxy
- je no_jmp
- jmp label02
- };
- no_jmp:
- asm jmp salida12
-
- label1a2:
- asm neg dx
- label1b2:
- asm{
- mov es:di,ax//guardar el offset primero
- add di,4 //calcular el nuevo offset
- add eax,edx
- sbb ax,-320
- sub cx,1
- jz term2b
- mov es:di,ax//guardar el offset primero
- add di,4 //calcular el nuevo offset
- add eax,edx
- sbb ax,-320
- loop label1b2//hasta terminar con el valor y2-y
- };
- term2b:
- asm{
- add si,4
- cmp si,mxy
- je salida12
- jmp label02
- };
- salida12:
- DRAW:
- asm{
- mov ax,color
- mov ah,al
- mov bx,ax
- shl eax,16
- mov ax,bx
- mov color1,eax
- mov si,es
- mov ds,si
- xor si,si
- mov ax,scrn
- mov es,ax
- mov bx,mxcnt
- and bx,255
- }
- loop_p2:
- asm{
- lodsd
- mov di,ax
- shr eax,16
- mov dx,ax
- cmp di,dx
- jz next
- jb norm_p
- xchg dx,di
- };
- norm_p:
- asm{
- sub dx,di
- and dx,1023
- jns pos_p
- neg dx
- };
- pos_p:
- asm{
- mov eax,color1
- cmp dx,4
- jle menos_de_una_linea
- mov cx,di
- and cx,3
- sub dx,cx
- rep stosb
- mov cx,dx
- shr cx,2
- rep stosd
- and dx,3
- };
- menos_de_una_linea:
- asm{
- mov cx,dx
- rep stosb
- };
- next:
- asm{
- sub bx,1
- jnz loop_p2
- };
- salida_p:
- asm{
- pop ds
- };
- }
-
- void box( int x1, int y1, int w, int h, int color, int segm )
- {
- asm{
- mov ax,x1
- mov bx,y1
- }
- getoff();
- asm{
- mov di,ax
- mov ax,segm
- mov es,ax
- mov si,w
- mov bx,h
- mov ax,color
- mov dx,320
- sub dx,si
- };
- looper:
- asm{
- mov cx,si
- rep stosb
- sub bx,1
- jz salida
- add di,dx
- jmp looper
- };
- salida:
- }
-
-
- //*************************VIDEO, BAJO NIVEL***************************
- // FUNCION: setvmode
- // ajusta el modo de video al especificado
- // parámetros: vmode - Modo de video
- // retorna: nada significativo.
- // destruye: AX.
-
- void setvmode( int v_mode )
- {
- asm{
- mov ax,v_mode
- sub ah,ah
- int 10h
- };
- }
-
- // FUNCION: getvmode
- // obtiene del sistema el modo de video actual
- // parámetros: NINGUNO.
- // retorna: Modo de video en AX.
- // destruye: AX
-
- int getvmode( void )
- {
- asm{
- mov ah,0Fh
- int 10h
- xor ah,ah
- };
- return _AX;
- }
-
- //************************TRAZOS GEOMÉTRICOS***************************
- void drawvline(void)
- { // comunicación por registro
- // color en ax, yi en bx, yf en cx, x en dx
- asm{
- sub cx,bx
- shl bx,1
- mov di,[bx+offset y_off]
- add di,dx
- mov dx,0A000h
- mov es,dx
- };
- dvl1:
- asm{
- mov es:[di],al
- add di,320
- loop dvl1
- };
- }
-
- //*************************** MISCELANEOS ******************************
-
- // FUNCIαN: valloc
- // reserva memoria a través de farmalloc, alinea el bloque a cero
- // y retorna sólo el segmento
- // parámetros: _asize - Tamaño del bloque pedido
- // retorna:
- // éxito:segmento del bloque alineado
- // error:CARRY y cero
-
- int valloc( unsigned long asize )
- { unsigned long size;
- asm{
- mov eax,asize
- add eax,16
- mov size,eax
- };
- farmalloc( size );
- return _DX+1;
- }
-
- // FUNCIαN: _vfree
- // libera un bloque de memoria reservado por _valloc
- // parámetros: segm, el segmento en cuestión
- // retorna lo mismo que farfree de alloc.h en Turbo c
-
- void vfree( unsigned int segm )
- { int result;
- void far *pointer;
-
- asm{
- mov ax,segm
- dec ax
- rol eax,16
- mov ax,4
- mov dword ptr pointer,eax
- };
- farfree( pointer );
- }
-
- void initclosed( void )
- {
- closed=valloc(2000);
- if(closed==1)
- {
- setvmode(old_mode);
- printf("\nMemoria insuficiente: error 2.");
- exit(0);
- };
- w_array=closed+8;
- x_array=(int far *)MK_FP( w_array, 0 );
- closed_ptr=(int far *)MK_FP( closed, 0 );
- }
-
- // FUNCIαN: getoff
- // retorna el offset de las coordenadas (para una pantalla de 320 x 200)
- // parámetros: AX: coordenada X
- // BX: coordenada Y
- // retorna:
- // éxito: AX: offset
-
- int getoff( void )
- {
- asm{
- push ds ax
- mov ax,seg y_off
- mov ds,ax
- add bx,bx
- pop ax
- add ax,[offset y_off + bx ]
- pop ds
- };
- return _AX;
- }
-
- //************************ MANEJO DE BITMAPS ***************************
- // FUNCIαN: _getimage
- // recupera una imagen de una pantalla virtual, reserva suficiente memoria
- // y la pone en el formato BGI ( dos palabras x_length y y_length y
- // porteriormente los datos en 8 bits por pixel )
- // parámetros:
- // se pasan por medio de la estructura gi_struc
- // gi_orig:segmento en que se encuentra la pantalla virtual de la que
- // se toma la imágen
- // gi_xo, gi_yo: X y Y superior izq. del origen
- // gi_wo: anchura de la imágen, en pixels
- // gi_ho: altura de la imágen en pixels
- // gi_xd, gi_yd: X y Y superior izq. del destino
- // las demás son variables internas y se sobreescriben al llamar a la función
- // retorna: AX: el segmento en que se colocó la imágen
- //
-
- int getimage( int orig, int xo, int yo, int wo, int ho )
- { int delta, gi_seg;
- asm{
- mov ax,xo
- mov bx,yo
- };
- getoff();
- asm{
- mov si,ax //guardar en si
- mov ax,wo //calcular el tamaño de la imágen
- mov cx,ho
- mul cx
- add ax,4
- cwde
- };
- valloc( _EAX ); //reservar memoria suficiente para ella
- asm{
- mov es,ax
- mov gi_seg,ax
- mov di,4
- mov ax,wo
- mov es:[0],ax
- mov ax,ho
- mov es:[2],ax
- mov dx,320
- sub dx,wo
- mov delta,dx
- mov ax,ds
- mov fs,ax
- mov ax,ho
- shl ax,8
- mov cx,wo
- mov dx,cx
- mov bx,delta
- mov ds,orig
- };
- gi_lineas:
- asm{
- rep movsb
- dec ah
- jz gi_sal
- add si,bx
- mov cx,dx
- jmp gi_lineas
- };
- gi_sal:
- asm{
- mov dx,fs
- mov ds,dx
- };
- return gi_seg;
- }
-
- // FUNCIαN: _putimage
- // pone en la pantalla especificada, la imágen pedida en modo PUT,
- // como su nombre lo indica
- // parámetros: ctrl_struc - puntero a la estructura de control 'objeto'
- // vsh - vs_handle de la pantalla destino
- // retorna: nada significativo
- //
-
- void putimage( int far *ctrl_struc, int dest )
- { int orig;
- asm{
- push ds
- lfs bx,ctrl_struc //segmento del struc de control
- mov ax,fs:[bx] //segmento orígen
- mov orig,ax //guardar en orig
- mov ax,fs:[bx+2]
- mov bx,fs:[bx+4]
- };
- getoff();
- asm{ //offset del punto de inicio
- mov di,ax
- mov ax,dest //handle de la pantalla destino
- mov es,ax
- mov ds,orig //cargar en fs el segmento de orígen
- mov si,4
- mov bx,ds:0
- mov dx,320
- sub dx,bx
- push bp
- mov bp,ds:[2]
- };
- lineas:
- asm{
- mov cx,bx
- rep movsb
- add di,dx
- dec bp
- jnz lineas
- pop bp
- pop ds
- };
- }
-
- // FUNCIαN: _drwimage
- // pone en la pantalla especificada, la imágen pedida, pero considera
- // al color negro como transparente
- // parámetros: ctrl_struc - puntero a la estructura de control 'objeto'
- // vsh - vs_handle de la pantalla destino
- // retorna: nada significativo
- //
-
- void drwimage( int far *ctrl_struc, int dest )
- { int orig;
- asm{
- push ds
- lfs bx,ctrl_struc //segmento del struc de control
- mov ax,fs:[bx] //segmento orígen
- mov orig,ax //guardar en orig
- mov ax,fs:[bx+2]
- mov bx,fs:[bx+4]
- };
- getoff();
- asm{ //offset del punto de inicio
- mov di,ax
- mov ax,dest //handle de la pantalla destino
- mov es,ax
- mov ds,orig //cargar en fs el segmento de orígen
- mov si,4
- mov bx,ds:0
- mov dx,320
- sub dx,bx
- push bp
- mov bp,ds:[2]
- }
- di_lineas:
- asm mov cx,bx
- di_loop:
- asm{
- mov al,ds:[si]
- or al,al
- jz nocolor
- mov es:[di],al
- };
- nocolor:
- asm{
- inc di
- inc si
- loop di_loop
- add di,dx
- dec bp
- jnz di_lineas
- pop bp
- pop ds
- };
- }
-
- // FUNCIαN: scale
- // escala un bitmap al tamaño especificado
- // parámetros:
- // se pasan a través de la estructura de control scl_struc:
- // variable tamaño
- // scl_orig dd puntero sg:of de la imágen origen y destino
- // scl_dest dd
- // scl_orw dw ancho y alto de la imágen origen
- // scl_orh dw
- // scl_dsw dw ancho y alto de la imágen destino
- // scl_dsh dw
- // scl_deltaw dd variables internas
- // scl_deltah dd
- // scl_psi dw
- //
-
- int scale(char far *orig, char far *dest, int orw, int orh, int dsw, int dsh )
- { long deltaw, deltah;
- int psi;
-
- asm{
- mov dx,dsw
- xor ax,ax
- mov bx,orw
- div bx
- mov word ptr deltaw,ax
- mov word ptr deltaw[2],dx
- mov dx,dsh
- xor ax,ax
- mov bx,orh
- div bx
- mov word ptr deltah,ax
- mov word ptr deltah[2],dx
- lds si,orig
- les di,dest
- mov edx,deltaw
- rol edx,16
- mov ebx,deltah
- rol ebx,16
- mov cx,bx
- mov ax,0FFFFh
- sub ax,dsh
- shl eax,16
- mov ax,0FFFFh
- };
- linea:
- asm mov psi,si
- asm mov cx,dsw
- pixel:
- asm{
- add esi,edx
- adc esi,0
- movsb
- dec si
- loop pixel
- add eax,10000h
- jc scl_salida
- mov si,psi
- add ecx,ebx
- adc cx,0
- };
- mult:
- asm{
- add si,orw
- loop mult
- jmp linea
- };
- scl_salida:
- return 0;
- }
-
- //*********************** PANTALLAS COMPLETAS ****************************
-
- // FUNCIαN: clear
- // borra la pantalla especificada al color deseado
- void clear( int c_color, int segm )
- {
- asm{
- mov ax,c_color
- mov bx,segm
- mov es,bx
- mov ah,al
- mov bx,ax
- rol eax,16
- mov ax,bx
- mov di,0
- mov cx,16100
- rep stosd
- };
- }
-
- // FUNCIαN: flip
- // pasa el contenido de una pantalla a otra
- // parámetros: orig - vs_handle de la pantalla orígen
- // dest - vs_handle de la pantalla destino
-
- void flip( int orig, int dest )
- {
- asm{
- mov cx,16100
- xor si,si
- mov di,si
- push ds
- mov es,dest
- mov ds,orig
- rep movsd
- pop ds
- };
- }
-
- // FUNCIαN: putblock
- // toma un bloque de una pantalla y lo pasa a otra
- // parámetros:
- // se pasan a través de la función pb_struc
- // orig:segmento de origen
- // orig: " " " destino
- // xo: X de la esquina superior izquierda del rectángulo de origen
- // yo: Y
- // wo: anchura del orígen en pixels
- // ho: altura
- // xd: X de la esquina superior izquierda del rectángulo destino
- // yd: Y
- // las otras variables del struc son variables internas que se sobreescriben
- // cada vez que se llama la función
- // retorna: nada significativo
-
- void putblock( int orig,int dest,int xo,int yo,int wo,int ho,int xd,int yd)
- { int o_of, d_of;
- asm{
- push ds
- mov ax,xo //offset del origen
- mov bx,yo
- };
- getoff();
- asm{
- mov si,ax
- mov ax,xd //offset del destino
- mov bx,yd
- };
- getoff();
- asm{
- mov di,ax
- mov bx,wo
- mov dx,320
- sub dx,bx
- shr bx,2
- jc pb_lineas8
- mov ds,orig
- mov es,dest
- push bp
- mov bp,ho
- };
- pb_lineas:
- asm{
- mov cx,bx
- rep movsd
- add si,dx
- add di,dx
- dec bp
- jnz pb_lineas
- pop bp
- pop ds
- jmp salida
- };
- pb_lineas8:
- asm{
- mov bx,wo
- mov ds,orig
- mov es,dest
- push bp
- mov bp,ho
- };
- pb_looper:
- asm{
- mov cx,bx
- rep movsb
- add si,dx
- add di,dx
- dec bp
- jnz pb_looper
- pop bp
- pop ds
- };
- salida:
- }
-
- // función: scroll_up
- //pone dos segmentos de una pantalla, en la otra
- // argumentos: orig - segmento de origen
- // dest - segmento destino
- // part - linea de partición
- // retorna: nada significativo
- // destruye todos los registros
-
- void scroll_up( int orig, int dest, int part)
- {
- asm{
- mov es,dest
- mov ds,orig
- mov bx,part
- add bx,part
- mov si,[bx+offset y_off]
- mov dx,si
- mov cx,64000
- sub cx,si
- sub di,di
- or cx,cx
- jz nothing1
- shr cx,1
- jnc su_nocarry1
- jz nothing1
- stosb
- };
- su_nocarry1:
- asm{
- shr cx,1
- jnc su_nocarry2
- jz nothing1
- stosw
- };
- su_nocarry2:
- asm rep movsd
- nothing1:
- asm{
- sub si,si
- mov cx,dx
- or cx,cx
- jz nothing2
- shr cx,1
- jnc su_nocarry3
- jz nothing2
- stosb
- };
- su_nocarry3:
- asm{
- shr cx,1
- jnc su_nocarry4
- jz nothing2
- stosw
- };
- su_nocarry4:
- asm rep movsd
- nothing2:
- asm pop ds
- }
-
-